<template>
	<view class="face-recognition-container">
		<!-- 标题区域 -->
		<view class="header">
			<text class="title">人脸登录</text>
			<text class="subtitle">请将面部对准摄像头进行登录</text>
		</view>

		<!-- 摄像头区域 -->
		<view class="camera-container">
			<camera 
				class="camera" 
				device-position="front"
				flash="off"
				@error="onCameraError"
				@initdone="onCameraReady"
				ref="camera">
				
				<!-- 人脸识别框 -->
				<view class="face-frame">
					<view class="corner top-left"></view>
					<view class="corner top-right"></view>
					<view class="corner bottom-left"></view>
					<view class="corner bottom-right"></view>
				</view>
				
				<!-- 识别状态提示 -->
				<view class="status-overlay" v-if="recognitionStatus">
					<text class="status-text" :class="statusClass">{{ recognitionStatus }}</text>
				</view>
			</camera>
		</view>

		<!-- 操作按钮区域 -->
		<view class="controls">
			<button 
				class="btn-primary" 
				@click="startRecognition"
				:disabled="isRecognizing || !cameraReady">
				{{ isRecognizing ? '登录中...' : '开始登录' }}
			</button>
			
			<button 
				class="btn-secondary" 
				@click="goBack">
				返回登录
			</button>
		</view>

		<!-- 识别结果区域 -->
		<view class="result-section" v-if="recognitionResult">
			<view class="result-card">
				<text class="result-title">识别结果</text>
				<view class="result-content">
					<text class="result-name" v-if="recognitionResult && recognitionResult.success && recognitionResult.user_info">
						{{ recognitionResult.user_info.username || recognitionResult.user_info.real_name }}
					</text>
					<text class="result-confidence" v-if="recognitionResult && recognitionResult.success && recognitionResult.recognition_confidence !== undefined">
						置信度: {{ (Number(recognitionResult.recognition_confidence) * 100).toFixed(1) }}%
					</text>
					<text class="result-message" v-if="recognitionResult && !recognitionResult.success">
						{{ recognitionResult.message }}
					</text>
				</view>
			</view>
		</view>

		<!-- 日志区域 -->
		<view class="log-section" v-if="logs.length > 0">
			<text class="log-title">操作日志</text>
			<scroll-view class="log-container" scroll-y="true">
				<view class="log-item" v-for="(log, index) in logs" :key="index">
					<text class="log-time">{{ log.time }}</text>
					<text class="log-message" :class="log.type">{{ log.message }}</text>
				</view>
			</scroll-view>
		</view>

		<!-- 警告提示 -->
		<view class="warning-box">
			<text class="warning-title">⚠️ 使用说明</text>
			<text class="warning-text">• 请确保Python端人脸识别服务已启动 ({{ apiBaseUrl.replace('/api', '') }})</text>
			<text class="warning-text">• 开发者工具不支持camera组件，请使用真机调试或预览模式</text>
			<text class="warning-text">• 首次使用需要授权摄像头权限</text>
			<text class="warning-text">• 识别时请保持面部清晰可见</text>
		</view>
	</view>
</template>

<script>
import apiConfig from '@/config/api.js'
import { mapMutations } from 'vuex'
import { setToken, setUserInfo } from '@/utils/auth.js'
import { faceLogin } from '@/api/auth.js'

export default {
	data() {
		return {
			cameraReady: false,
			isRecognizing: false,
			recognitionStatus: '',
			recognitionResult: null,
			logs: [],
			statusClass: '',
			registerName: '',
			showRegisterDialog: false,
			// API配置 - 从配置文件获取
			apiBaseUrl: apiConfig.baseUrl
		}
	},
	
	onLoad() {
		this.addLog('页面加载完成', 'info');
	},
	
	methods: {
		...mapMutations('user', ['setUserInfo', 'setToken']),
		
		// 摄像头准备就绪
		onCameraReady() {
			this.cameraReady = true;
			this.addLog('摄像头初始化成功', 'success');
		},
		
		// 摄像头错误处理
		onCameraError(error) {
			console.error('摄像头错误:', error);
			this.addLog('摄像头错误: ' + JSON.stringify(error), 'error');
			
			// 检查是否是开发者工具限制
			if (error.errMsg && error.errMsg.includes('not support')) {
				uni.showModal({
					title: '提示',
					content: '摄像头组件需要在真机上测试，请使用真机调试或预览功能',
					showCancel: false
				});
			} else {
				uni.showToast({
					title: '摄像头启动失败',
					icon: 'none'
				});
			}
		},
		
		// 开始人脸识别
		async startRecognition() {
			if (!this.cameraReady) {
				uni.showToast({
					title: '摄像头未就绪',
					icon: 'none'
				});
				return;
			}
			
			this.isRecognizing = true;
			this.recognitionStatus = '正在拍照...';
			this.statusClass = 'status-processing';
			this.recognitionResult = null;
			
			try {
				// 拍照
				const photo = await this.takePhoto();
				this.addLog('拍照成功', 'success');
				
				this.recognitionStatus = '正在识别...';
				
				// 调用人脸识别API
				const result = await this.callRecognitionAPI(photo.tempImagePath);
				
				this.recognitionResult = result;
				//打印result
				console.log('人脸识别API返回结果:', result);
				
				// 添加到界面日志中，方便调试
				this.addLog(`API返回结果: ${JSON.stringify(result)}`, 'info');
				
				// 检查响应格式并保存token和用户信息（统一格式）
				let token, userInfo
				let loginSuccess = false
				
				// 添加调试日志
				console.log('API返回的原始数据:', result);
				this.addLog(`API原始数据: ${JSON.stringify(result)}`, 'info');
				
				if (result.success && result.token) {
					// 统一后的响应格式（Python和Java都使用这种格式）
					token = result.token
					userInfo = result.userInfo
					loginSuccess = true
				}
				
				// 打印用户信息调试
				console.log('解析后的userInfo:', userInfo);
				this.addLog(`解析后的userInfo: ${JSON.stringify(userInfo)}`, 'info');
				
				if (loginSuccess) {
					this.recognitionStatus = '登录成功';
					this.statusClass = 'status-success';
					this.addLog(`登录成功: ${userInfo.real_name || userInfo.username}`, 'success');
					
					// 字段映射：统一后的字段格式
				const mappedUserInfo = {
					...userInfo,
					email: userInfo.email || '未设置',
					realName: userInfo.realName || userInfo.username,
					department: userInfo.department || '未设置',
					position: userInfo.position || (userInfo.roles && userInfo.roles[0]) || '未设置',
					avatar: userInfo.avatar || '/static/logo.png'
				};
					
					// 同时更新本地存储和Vuex store
					setToken(token);
					setUserInfo(mappedUserInfo);
					this.setToken(token);
					this.setUserInfo(mappedUserInfo);
					
					this.addLog('用户信息已保存到本地存储和Vuex store', 'success');
					
					// 显示成功提示
					uni.showToast({
						title: '登录成功',
						icon: 'success',
						duration: 1500
					});
					
					// 跳转到首页
					setTimeout(() => {
						uni.switchTab({
							url: '/pages/index/index',
							success: () => {
								this.addLog('跳转首页成功', 'success');
							},
							fail: (err) => {
								this.addLog('跳转首页失败: ' + JSON.stringify(err), 'error');
								uni.showToast({ title: '跳转失败', icon: 'none' });
							}
						});
					}, 1500);
					
				} else {
					this.recognitionStatus = '登录失败';
					this.statusClass = 'status-error';
					const errorMessage = result.message || result.msg || '登录失败'
					this.addLog(`登录失败: ${errorMessage}`, 'error');
				}
				
			} catch (error) {
				console.error('登录过程出错:', error);
				this.recognitionStatus = '登录出错';
				this.statusClass = 'status-error';
				this.addLog('登录过程出错: ' + error.message, 'error');
				
				uni.showToast({
					title: '登录失败',
					icon: 'none'
				});
			} finally {
				this.isRecognizing = false;
				// 3秒后清除状态
				setTimeout(() => {
					this.recognitionStatus = '';
				}, 3000);
			}
		},
		
		// 拍照
		takePhoto() {
			return new Promise((resolve, reject) => {
				const ctx = uni.createCameraContext();
				ctx.takePhoto({
					quality: 'high',
					success: (res) => {
						resolve(res);
					},
					fail: (error) => {
						reject(new Error('拍照失败: ' + JSON.stringify(error)));
					}
				});
			});
		},
		
		// 调用人脸登录API
		async callRecognitionAPI(imagePath) {
			try {
				// 将图片转换为base64
				const base64Data = await this.imageToBase64(imagePath);
				
				// 使用auth.js中的faceLogin函数调用人脸登录接口
				const result = await faceLogin({
					image: `data:image/jpeg;base64,${base64Data}`
				});
				
				return result;
			} catch (error) {
				console.error('调用人脸登录API失败:', error);
				throw new Error('人脸登录失败: ' + (error.message || '网络请求失败'));
			}
		},
		
		// 调用注册API
		async callRegisterAPI(imagePath, name) {
			try {
				// 将图片转换为base64
				const base64Data = await this.imageToBase64(imagePath);
				
				// 调用注册接口
				const [err, res] = await uni.request({
					url: `${this.apiBaseUrl}/register`,
					method: 'POST',
					header: {
						'Content-Type': 'application/json'
					},
					data: {
						name: name,
						image: base64Data
					}
				});
				
				if (err) {
					console.error('注册请求错误:', err);
					throw new Error('网络请求失败，请检查Python服务是否启动');
				}
				
				if (res && res.statusCode === 200) {
					return res.data;
				} else {
					const code = res ? res.statusCode : '未知';
					throw new Error(`API请求失败: ${code}`);
				}
			} catch (error) {
				console.error('调用注册API失败:', error);
				throw new Error('网络请求失败，请检查Python服务是否启动');
			}
		},
		
		// 图片转base64
		imageToBase64(imagePath) {
			return new Promise((resolve, reject) => {
				uni.getFileSystemManager().readFile({
					filePath: imagePath,
					encoding: 'base64',
					success: (res) => {
						resolve(res.data);
					},
					fail: (error) => {
						reject(new Error('读取图片失败: ' + JSON.stringify(error)));
					}
				});
			});
		},
		
		// 添加日志
		addLog(message, type = 'info') {
			const now = new Date();
			const time = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
			
			this.logs.unshift({
				time,
				message,
				type
			});
			
			// 限制日志数量
			if (this.logs.length > 50) {
				this.logs = this.logs.slice(0, 50);
			}
		},
		
		// 返回登录页面
		goBack() {
			uni.navigateBack({
				delta: 1
			});
		}
	}
}
</script>

<style scoped>
.face-recognition-container {
	padding: 20rpx;
	background-color: #f5f5f5;
	min-height: 100vh;
}

.header {
	text-align: center;
	margin-bottom: 30rpx;
}

.title {
	display: block;
	font-size: 36rpx;
	font-weight: bold;
	color: #333;
	margin-bottom: 10rpx;
}

.subtitle {
	display: block;
	font-size: 28rpx;
	color: #666;
}

.camera-container {
	position: relative;
	width: 100%;
	height: 500rpx;
	margin-bottom: 30rpx;
	border-radius: 20rpx;
	overflow: hidden;
	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
}

.camera {
	width: 100%;
	height: 100%;
	background-color: #000;
}

.face-frame {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 300rpx;
	height: 400rpx;
	border: 4rpx solid rgba(0, 122, 255, 0.8);
	border-radius: 20rpx;
}

.corner {
	position: absolute;
	width: 40rpx;
	height: 40rpx;
	border: 6rpx solid #007AFF;
}

.corner.top-left {
	top: -6rpx;
	left: -6rpx;
	border-right: none;
	border-bottom: none;
	border-top-left-radius: 20rpx;
}

.corner.top-right {
	top: -6rpx;
	right: -6rpx;
	border-left: none;
	border-bottom: none;
	border-top-right-radius: 20rpx;
}

.corner.bottom-left {
	bottom: -6rpx;
	left: -6rpx;
	border-right: none;
	border-top: none;
	border-bottom-left-radius: 20rpx;
}

.corner.bottom-right {
	bottom: -6rpx;
	right: -6rpx;
	border-left: none;
	border-top: none;
	border-bottom-right-radius: 20rpx;
}

.status-overlay {
	position: absolute;
	bottom: 20rpx;
	left: 50%;
	transform: translateX(-50%);
	background-color: rgba(0, 0, 0, 0.7);
	padding: 10rpx 20rpx;
	border-radius: 20rpx;
}

.status-text {
	color: #fff;
	font-size: 28rpx;
	font-weight: bold;
}

.status-processing {
	color: #ffc107;
}

.status-success {
	color: #28a745;
}

.status-error {
	color: #dc3545;
}

.controls {
	display: flex;
	justify-content: space-between;
	margin-bottom: 30rpx;
	gap: 20rpx;
}

.btn-primary {
	flex: 1;
	height: 80rpx;
	line-height: 80rpx;
	background: linear-gradient(135deg, #007AFF, #0056CC);
	border: none;
	border-radius: 40rpx;
	font-size: 32rpx;
	color: #fff;
	font-weight: bold;
}

.btn-primary:disabled {
	background: #ccc;
	color: #999;
}

.btn-secondary {
	flex: 1;
	height: 80rpx;
	line-height: 80rpx;
	background: #fff;
	border: 2rpx solid #007AFF;
	border-radius: 40rpx;
	font-size: 32rpx;
	color: #007AFF;
	font-weight: bold;
}

.btn-secondary:disabled {
	background: #f5f5f5;
	border-color: #ccc;
	color: #999;
}

.result-section {
	margin-bottom: 30rpx;
}

.result-card {
	background-color: #fff;
	border-radius: 20rpx;
	padding: 30rpx;
	box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}

.result-title {
	display: block;
	font-size: 32rpx;
	font-weight: bold;
	color: #333;
	margin-bottom: 20rpx;
}

.result-content {
	text-align: center;
}

.result-name {
	display: block;
	font-size: 36rpx;
	font-weight: bold;
	color: #007AFF;
	margin-bottom: 10rpx;
}

.result-confidence {
	display: block;
	font-size: 28rpx;
	color: #28a745;
	margin-bottom: 10rpx;
}

.result-message {
	display: block;
	font-size: 28rpx;
	color: #dc3545;
}

.log-section {
	margin-bottom: 30rpx;
}

.log-title {
	display: block;
	font-size: 28rpx;
	font-weight: bold;
	color: #333;
	margin-bottom: 15rpx;
}

.log-container {
	background-color: #fff;
	border-radius: 15rpx;
	padding: 20rpx;
	max-height: 300rpx;
	box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}

.log-item {
	display: flex;
	margin-bottom: 10rpx;
	padding-bottom: 10rpx;
	border-bottom: 1rpx solid #f0f0f0;
}

.log-time {
	font-size: 24rpx;
	color: #999;
	margin-right: 15rpx;
	min-width: 120rpx;
}

.log-message {
	font-size: 26rpx;
	flex: 1;
}

.log-message.info {
	color: #333;
}

.log-message.success {
	color: #28a745;
}

.log-message.error {
	color: #dc3545;
}

.warning-box {
	background-color: #fff3cd;
	border: 1rpx solid #ffeaa7;
	border-radius: 15rpx;
	padding: 20rpx;
	margin-bottom: 20rpx;
}

.warning-title {
	display: block;
	font-size: 28rpx;
	font-weight: bold;
	color: #856404;
	margin-bottom: 10rpx;
}

.warning-text {
	display: block;
	font-size: 24rpx;
	color: #856404;
	line-height: 1.5;
}

/* 注册对话框样式 */
.register-dialog-mask {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: rgba(0, 0, 0, 0.5);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 9999;
}

.register-dialog {
	background-color: #fff;
	border-radius: 20rpx;
	width: 600rpx;
	max-width: 90%;
	box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.3);
}

.dialog-header {
	padding: 40rpx 30rpx 20rpx;
	text-align: center;
	border-bottom: 1rpx solid #f0f0f0;
}

.dialog-title {
	font-size: 32rpx;
	font-weight: bold;
	color: #333;
}

.dialog-content {
	padding: 30rpx;
}

.dialog-message {
	display: block;
	font-size: 28rpx;
	color: #666;
	margin-bottom: 20rpx;
}

.dialog-input {
	width: 100%;
	height: 80rpx;
	border: 1rpx solid #ddd;
	border-radius: 10rpx;
	padding: 0 20rpx;
	font-size: 28rpx;
	box-sizing: border-box;
}

.dialog-input:focus {
	border-color: #007AFF;
}

.dialog-buttons {
	display: flex;
	border-top: 1rpx solid #f0f0f0;
}

.dialog-btn {
	flex: 1;
	height: 88rpx;
	line-height: 88rpx;
	text-align: center;
	font-size: 28rpx;
	border: none;
	background-color: transparent;
	border-radius: 0;
}

.dialog-btn:after {
	border: none;
}

.cancel-btn {
	color: #666;
	border-right: 1rpx solid #f0f0f0;
}

.confirm-btn {
	color: #007AFF;
	font-weight: bold;
}

.dialog-btn:active {
	background-color: #f5f5f5;
}
</style>